﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ComTools
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            InitComports();
            InitCommands12();
            StateShow();
            //
            InitCommands2();
            InitComports2();
            InitOthers();
            //
            //textBox1.Text = "01 04 00 00 00 20 F1 D2";
            //
            minvoker = new MethodInvoker(StateShow);

            form_timer = new System.Threading.Timer(
                new System.Threading.TimerCallback((object obj) =>
                {
                    if (this.IsHandleCreated)
                    {
                        this.BeginInvoke(minvoker);
                    }
                }), null, 1000, 1000);
            //
            serialPort1.DataReceived += serialPort1_DataReceived;
            serialPort2.DataReceived += serialPort2_DataReceived;
            serialPort3.DataReceived += serialPort3_DataReceived;
            //
            initPage3();
            serialPort4.DataReceived += SerialPort4_DataReceived;
        }

        #region TabPage1

        private void btnLoadComports_Click(object sender, EventArgs e)
        {
            InitComports();
        }

        private void InitComports()
        {
            cmbxComports.Items.Clear();
            cmbxComports.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
            if (cmbxComports.Items.Count > 0)
            {
                cmbxComports.SelectedIndex = 0;
                btnOpenCom.Enabled = true;
            }
            else
            {
                btnOpenCom.Enabled = false;
            }
            //
            cmbBaudRate.SelectedIndex = 2;
            //
            String[] bitsSource = Enum.GetNames(typeof(System.IO.Ports.StopBits));
            cmbStopBits.DataSource = bitsSource;
            cmbStopBits.SelectedIndex = Array.IndexOf(bitsSource, System.IO.Ports.StopBits.One.ToString());
            String[] paritySource = Enum.GetNames(typeof(System.IO.Ports.Parity));
            cmbParity.DataSource = paritySource;
            cmbParity.SelectedIndex = Array.IndexOf(paritySource, System.IO.Ports.Parity.None.ToString());
        }

        private void InitCommands12()
        {
            List<KeyValuePair<string, KeyValuePair<string, string>[]>> list = new List<KeyValuePair<string, KeyValuePair<string, string>[]>>();

            list.Add(new KeyValuePair<string, KeyValuePair<string, string>[]>("ZH-YX3232", new KeyValuePair<string, string>[] {
                new KeyValuePair<string, string>("ZH-YX3232-读01地址命令", "01 04 00 00 00 20 F1 D2"),
                new KeyValuePair<string, string>("ZH-YX3232-读02地址命令", "02 04 00 00 00 20 F1 E1"),
                new KeyValuePair<string, string>("ZH-YX3232-读03地址命令", "03 04 00 00 00 20 F0 30"),
                new KeyValuePair<string, string>("ZH-YX3232-设置地址01为02命令", "01 06 00 00 00 02 08 0B"),
                new KeyValuePair<string, string>("ZH-YX3232-设置地址01为03命令", "01 06 00 00 00 03 C9 CB"),
                new KeyValuePair<string, string>("ZH-YX3232-设置地址02为01命令", "02 06 00 00 00 01 48 39"),
                new KeyValuePair<string, string>("ZH-YX3232-设置地址03为01命令", "03 06 00 00 00 01 49 E8")
            }));
            list.Add(new KeyValuePair<string, KeyValuePair<string, string>[]>("E820-DTU(2I2433)", new KeyValuePair<string, string>[] {
                new KeyValuePair<string, string>("E820-DTU(2I2433)_地址01查询AI1的值", "01 03 00 11 00 01 D4 0F"),
                new KeyValuePair<string, string>("E820-DTU(2I2433)_地址01查询AI2的值", "01 03 00 12 00 01 24 0F"),
                new KeyValuePair<string, string>("E820-DTU(2I2433)_地址01查询AI1和AI2的值", "01 03 00 11 00 02 94 0E"),
                new KeyValuePair<string, string>("E820-DTU(2I2433)_地址01读取当前无线信道", "01 03 00 54 00 01 C5 DA"),
                new KeyValuePair<string, string>("E820-DTU(2I2433)_地址01读取当前响应时间", "01 03 00 55 00 01 94 1A"),
                new KeyValuePair<string, string>("E820-DTU(2I2433)_地址01修改485地址为02", "01 06 00 51 00 02 59 DA"),
                new KeyValuePair<string, string>("E820-DTU(2I2433)_地址02修改485地址为01", "02 06 00 51 00 01 19 E8"),
                new KeyValuePair<string, string>("E820-DTU(2I2433)_地址02查询AI1的值", "02 03 00 11 00 01 D4 3C"),
                new KeyValuePair<string, string>("E820-DTU(2I2433)_地址02查询AI2的值", "02 03 00 12 00 01 24 3C"),
                new KeyValuePair<string, string>("E820-DTU(2I2433)_地址02查询AI1和AI2的值", "02 03 00 11 00 02 94 3D"),
            }));
            list.Add(new KeyValuePair<string, KeyValuePair<string, string>[]>("IWIR417", new KeyValuePair<string, string>[] {
                new KeyValuePair<string, string>("IWIR417_读地址01的8个寄存器命令", "01 04 00 40 00 08 F0 18"),
                new KeyValuePair<string, string>("IWIR417_读地址02的8个寄存器命令", "02 04 00 40 00 08 F0 2B"),
                new KeyValuePair<string, string>("IWIR417_读地址03的8个寄存器命令", "03 04 00 40 00 08 F1 FA"),
                new KeyValuePair<string, string>("IWIR417_读地址04的8个寄存器命令", "04 04 00 40 00 08 F0 4D"),
            }));
            list.Add(new KeyValuePair<string, KeyValuePair<string, string>[]>("电子压力表", new KeyValuePair<string, string>[] {
                new KeyValuePair<string, string>("电子压力表解锁写入", "01 06 00 00 04 57 CA F4"),
                new KeyValuePair<string, string>("电子压力表修改地址为2", "01 06 00 01 00 02 59 CB"),
                new KeyValuePair<string, string>("电子压力表修改1位小数", "01 06 00 05 00 01 58 0B"),
                new KeyValuePair<string, string>("电子压力表修改kgf/cm2单位", "01 06 00 06 00 01 A8 0B"),
                new KeyValuePair<string, string>("电子压力表保存写入", "01 06 00 00 08 AE 0F B6"),
            }));
            list.Add(new KeyValuePair<string, KeyValuePair<string, string>[]>("超声皮流量计", new KeyValuePair<string, string>[] {
                new KeyValuePair<string, string>("超声皮流量计_地址01瞬时流量REAL4", "01 03 00 00 00 02 C4 0B"),
                new KeyValuePair<string, string>("超声皮流量计_地址01瞬时流量单位", "01 03 05 9C 00 01 44 E8"),
                new KeyValuePair<string, string>("超声皮流量计_地址01流体速度REAL4", "01 03 00 04 00 02 85 CA"),
                new KeyValuePair<string, string>("超声皮流量计_地址01正累积流量整数部分LONG", "01 03 00 08 00 02 45 C9"),
                new KeyValuePair<string, string>("超声皮流量计_地址01正累积流量小数部分REAL4", "01 03 00 0A 00 02 E4 09"),
                new KeyValuePair<string, string>("超声皮流量计_地址01累计流量单位", "01 03 05 9D 00 01 15 28"),
            }));
            list.Add(new KeyValuePair<string, KeyValuePair<string, string>[]>("温度传感器", new KeyValuePair<string, string>[] {
                new KeyValuePair<string, string>("温度传感器地址01查询温度", "01 03 00 C0 00 04 44 35"),
            }));
            list.Add(new KeyValuePair<string, KeyValuePair<string, string>[]>("E820-AIO(II-485-4-20)", new KeyValuePair<string, string>[] {
                new KeyValuePair<string, string>("E820-AIO(II-485-4-20)_地址01查询AI1-AI4的值", "01 03 00 0C 00 04 84 0A"),
                new KeyValuePair<string, string>("E820-AIO(II-485-4-20)_地址01查询AI1的值", "01 03 00 0C 00 01 44 09"),
                new KeyValuePair<string, string>("E820-AIO(II-485-4-20)_地址01查询AI2的值", "01 03 00 0D 00 01 15 C9"),
                new KeyValuePair<string, string>("E820-AIO(II-485-4-20)_地址01读取输入量程", "01 03 00 29 00 01 55 C2"),
                new KeyValuePair<string, string>("E820-AIO(II-485-4-20)_地址01修改485地址为02", "01 06 00 20 00 02 09 C1"),
                new KeyValuePair<string, string>("E820-AIO(II-485-4-20)_地址02修改485地址为01", "02 06 00 20 00 01 49 F3"),
                new KeyValuePair<string, string>("E820-AIO(II-485-4-20)_地址02查询AI1的值", "02 03 00 0C 00 01 44 3A"),
                new KeyValuePair<string, string>("E820-AIO(II-485-4-20)_地址02查询AI2的值", "02 03 00 0D 00 01 15 FA"),
                new KeyValuePair<string, string>("E820-AIO(II-485-4-20)_地址02查询AI1-AI4的值", "02 03 00 0C 00 04 84 39"),
                new KeyValuePair<string, string>("E820-AIO(II-485-4-20)_地址02读取输入量程", "02 03 00 29 00 01 55 F1"),
            }));
            //dic.Add("", new KeyValuePair<string, string>[] { });
            //
            cmbDeviceType.DataSource = list;
            cmbDeviceType.DisplayMember = "Key";
            cmbDeviceType.ValueMember = "Key";
            cmbDeviceType.SelectedIndexChanged += CmbDeviceType_SelectedIndexChanged;
            cmbDeviceType.SelectedIndex = 0;
            CmbDeviceType_SelectedIndexChanged(cmbDeviceType, new EventArgs());
        }

        private void CmbDeviceType_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox cmb = sender as ComboBox;
            KeyValuePair<string, KeyValuePair<string, string>[]> kvp = (KeyValuePair<string, KeyValuePair<string, string>[]>)cmb.SelectedItem;
            KeyValuePair<string, string>[] vs = kvp.Value;

            cmbDeviceCommand.DataSource = vs;
            cmbDeviceCommand.DisplayMember = "Key";
            cmbDeviceCommand.ValueMember = "Value";
            //
            cmbDeviceCommand.SelectedIndexChanged += cmbDeviceCommand_SelectedIndexChanged;
            //
            cmbDeviceCommand.SelectedIndex = 0;
            cmbDeviceCommand_SelectedIndexChanged(cmbDeviceCommand, new EventArgs());
        }

        private void InitCommands()
        {
            List<KeyValuePair<String, String>> lists = new List<KeyValuePair<string, string>>();
            lists.Add(new KeyValuePair<string, string>("ZH-YX3232-读01地址命令", "01 04 00 00 00 20 F1 D2"));
            lists.Add(new KeyValuePair<string, string>("ZH-YX3232-读02地址命令", "02 04 00 00 00 20 F1 E1"));
            lists.Add(new KeyValuePair<string, string>("ZH-YX3232-读03地址命令", "03 04 00 00 00 20 F0 30"));
            lists.Add(new KeyValuePair<string, string>("ZH-YX3232-设置地址01为02命令", "01 06 00 00 00 02 08 0B"));
            lists.Add(new KeyValuePair<string, string>("ZH-YX3232-设置地址01为03命令", "01 06 00 00 00 03 C9 CB"));
            lists.Add(new KeyValuePair<string, string>("ZH-YX3232-设置地址02为01命令", "02 06 00 00 00 01 48 39"));
            lists.Add(new KeyValuePair<string, string>("ZH-YX3232-设置地址03为01命令", "03 06 00 00 00 01 49 E8"));

            lists.Add(new KeyValuePair<string, string>("E820-DTU(2I2433)3地址01查询AI1", "01 03 00 11 00 01 D4 0F"));
            lists.Add(new KeyValuePair<string, string>("E820-DTU(2I2433)3地址01查询AI2", "01 03 00 12 00 01 24 0F"));
            lists.Add(new KeyValuePair<string, string>("E820-DTU(2I2433)3地址01查询AI1&2", "01 03 00 11 00 02 94 0E"));

            lists.Add(new KeyValuePair<string, string>("IWIR417读地址01的8个寄存器命令", "01 04 00 40 00 08 F0 18"));
            lists.Add(new KeyValuePair<string, string>("IWIR417读地址02的8个寄存器命令", "02 04 00 40 00 08 F0 2B"));
            lists.Add(new KeyValuePair<string, string>("IWIR417读地址03的8个寄存器命令", "03 04 00 40 00 08 F1 FA"));
            lists.Add(new KeyValuePair<string, string>("IWIR417读地址04的8个寄存器命令", "04 04 00 40 00 08 F0 4D"));

            lists.Add(new KeyValuePair<string, string>("电子压力表解锁", "01 06 00 00 04 57 CA F4"));
            lists.Add(new KeyValuePair<string, string>("电子压力表修改地址为2", "01 06 00 01 00 02 59 CB"));
            lists.Add(new KeyValuePair<string, string>("电子压力表修改1位小数", "01 06 00 05 00 01 58 0B"));
            lists.Add(new KeyValuePair<string, string>("电子压力表修改kgf/cm2单位", "01 06 00 06 00 01 A8 0B"));
            lists.Add(new KeyValuePair<string, string>("电子压力表写入", "01 06 00 00 08 AE 0F B6"));

            lists.Add(new KeyValuePair<string, string>("超声皮流量计地址01瞬时流量REAL4", "01 03 00 00 00 02 C4 0B"));
            lists.Add(new KeyValuePair<string, string>("超声皮流量计地址01瞬时流量单位", "01 03 05 9C 00 01 44 E8"));
            lists.Add(new KeyValuePair<string, string>("超声皮流量计地址01流体速度REAL4", "01 03 00 04 00 02 85 CA"));
            lists.Add(new KeyValuePair<string, string>("超声皮流量计地址01正累积流量整数部分LONG", "01 03 00 08 00 02 45 C9"));
            lists.Add(new KeyValuePair<string, string>("超声皮流量计地址01正累积流量小数部分REAL4", "01 03 00 0A 00 02 E4 09"));
            lists.Add(new KeyValuePair<string, string>("超声皮流量计地址01累计流量单位", "01 03 05 9D 00 01 15 28"));

            lists.Add(new KeyValuePair<string, string>("温度传感器地址01查询温度", "01 03 00 C0 00 04 44 35"));

            //
            cmbDeviceCommand.DataSource = lists;
            cmbDeviceCommand.DisplayMember = "Key";
            cmbDeviceCommand.ValueMember = "Value";
            //
            cmbDeviceCommand.SelectedIndexChanged += cmbDeviceCommand_SelectedIndexChanged;
            //
            cmbDeviceCommand.SelectedIndex = 0;
            cmbDeviceCommand_SelectedIndexChanged(cmbDeviceCommand, new EventArgs());
        }

        private void SetState(bool open)
        {
            btnLoadComports.Enabled = !open;
            if (System.IO.Ports.SerialPort.GetPortNames().Length > 0)
            {
                btnOpenCom.Enabled = !open;
                btnClose.Enabled = open;
            }
            else
            {
                btnOpenCom.Enabled = false;
                btnClose.Enabled = false;
            }
            btnSend.Enabled = serialPort1.IsOpen;
            btnAlarmOpen.Enabled = serialPort1.IsOpen;
            btnAlarmClose.Enabled = serialPort1.IsOpen;
            cmbxComports.Enabled = !serialPort1.IsOpen;
            cmbBaudRate.Enabled = !serialPort1.IsOpen;
            cmbStopBits.Enabled = !serialPort1.IsOpen;
            cmbParity.Enabled = !serialPort1.IsOpen;
            txtDataBits.ReadOnly = serialPort1.IsOpen;
            nudBytesThreshold.Increment = serialPort1.IsOpen ? 0 : 1;
            nudBytesThreshold.Enabled = !serialPort1.IsOpen;
            //
            //btnSend.Enabled = serialPort2.IsOpen;
            //cmbxComports2.Enabled = !serialPort2.IsOpen;
        }

        void cmbDeviceCommand_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (sender is ComboBox)
            {
                ComboBox cb = sender as ComboBox;
                if (cb.SelectedIndex >= 0)
                {
                    txtInputPage1.Text = cb.SelectedValue.ToString();
                }
            }
        }

        System.Threading.Timer form_timer = null;

        private void serialPort3_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort serialPort = (SerialPort)sender;
            System.Threading.Thread.Sleep(200);
            byte[] buffers = new byte[serialPort1.BytesToRead];
            serialPort.Read(buffers, 0, buffers.Length);
            String recHex = BitConverter.ToString(buffers);

        }

        MethodInvoker minvoker = null;

        private void StateShow()
        {
            tsslNow.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            tsslState.Text = serialPort1.PortName + ":" + serialPort1.IsOpen.ToString();
            tsslCom.Text = String.Format("{0},{1},{2},{3}", serialPort1.BaudRate, serialPort1.Parity, serialPort1.DataBits, (int)serialPort1.StopBits);
            SetState(serialPort1.IsOpen);
        }

        private void btnOpenCom_Click(object sender, EventArgs e)
        {
            if (cmbxComports.SelectedIndex < 0)
            {
                return;
            }
            String compName = cmbxComports.SelectedItem.ToString();
            serialPort1.PortName = compName;
            //
            serialPort1.BaudRate = int.Parse(cmbBaudRate.SelectedItem.ToString());
            serialPort1.DataBits = int.Parse(txtDataBits.Text.Trim());
            serialPort1.StopBits = (System.IO.Ports.StopBits)Enum.Parse(typeof(System.IO.Ports.StopBits), cmbStopBits.SelectedItem.ToString());
            serialPort1.Parity = (System.IO.Ports.Parity)Enum.Parse(typeof(System.IO.Ports.Parity), cmbParity.SelectedItem.ToString());
            serialPort1.ReceivedBytesThreshold = (int)nudBytesThreshold.Value;
            //
            if (cbxComMode.Checked)
            {
                //文本模式

            }
            else
            {
                //二进制模式

            }
            //
            try
            {
                serialPort1.Open();
                StateShow();
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            StateShow();
        }

        string SmsCenterAddress;

        private void serialPort2_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            SerialPort serialPort = sender as SerialPort;
            System.Threading.Thread.Sleep(200);
            String recStr = serialPort.ReadExisting();

            if (!this.IsDisposed)
            {
                this.Invoke(new MethodInvoker(() =>
                {
                    txtOutput2.AppendText(recStr);
                    txtOutput2.AppendText(Environment.NewLine);
                }));
            }

            String xx = recStr.Trim();
            //发送英文短信
            if (xx.StartsWith("AT+CMGF=1") && xx.EndsWith("OK"))
            {
                //如果设置消息格式为TEXT
                //选择GSM字符集
                serialPort.WriteLine("AT+CSCS=\"GSM\"");
            }
            else if (xx.StartsWith("AT+CSCS=\"GSM\"") && xx.EndsWith("OK"))
            {
                //如果设置GSM成功
                //则设置收件人
                serialPort.WriteLine("AT+CMGS=\"13952458812\"");
            }
            else if (xx.StartsWith("AT+CMGS=\"") && xx.EndsWith(">"))
            {
                //如果设置收件人成功
                //则发送短消息
                //String ctrlZ = "\u001A";
                //serialPort.WriteLine("helloWorld" + ctrlZ);
                //serialPort.Write("helloWorld" + ctrlZ);
                serialPort.Write("Alarms Occors" + (char)26);
            }
            else if (!xx.StartsWith("AT") && xx.EndsWith("OK"))
            {
                this.BeginInvoke(new MethodInvoker(() =>
                {
                    MessageBox.Show("已发送成功");
                }));
            }
            //
            else if (xx.StartsWith("AT+CSCA?") && xx.EndsWith("OK"))
            {
                string[] arrays = xx.Split('\"');
                if (arrays.Length == 3)
                {
                    SmsCenterAddress = arrays[1].Replace("+", "");
                    //this.BeginInvoke(new MethodInvoker(() =>
                    //{
                    //    textBox6.Text = SmsCenterAddress;
                    //}));
                }
            }
            else if (xx.StartsWith("AT+CMGF=0") && xx.EndsWith("OK"))
            {
                //如果设置消息格式为PUT
                //则设置 选择字符集TE字符集
                serialPort.WriteLine("AT+CSCS=\"UCS2\"");
            }
            else if (xx.StartsWith("AT+CSCS=\"UCS2\"") && xx.EndsWith("OK"))
            {
                //如果 选择字符集TE字符集 成功
                //则查询短信配置中心地址
                //    serialPort.WriteLine("AT+CSCA?");
                //}
                //else if (xx.StartsWith("AT+CSCA?") && xx.EndsWith("OK"))
                //{
                //如果 查询短信配置中心地址 成功
                //则设置 设置短信内容长度
                if (message != null)
                {
                    serialPort.WriteLine("AT+CMGS=" + message.AtCmgsLength.ToString());
                }
            }
            else if (xx.StartsWith("AT+CMGS=") && xx.EndsWith(">"))
            {
                //如果短信内容长度设置成功
                //则发送短信
                if (message != null)
                {
                    serialPort.WriteLine(message.ToString());
                }
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            if (cbxComMode.Checked)
            {
                System.Threading.Thread.Sleep(100);
            }
            else
            {
                int i = (int)nudSleepTime.Value;
                System.Threading.Thread.Sleep(i);
            }
            byte[] buffers = new byte[serialPort1.BytesToRead];
            serialPort1.Read(buffers, 0, buffers.Length);
            //
            String recHex = BitConverter.ToString(buffers);
            //
            String newCrc = String.Empty;
            //
            if (!this.IsDisposed)
            {
                this.Invoke(new MethodInvoker(() =>
                {
                    txtLogPage1.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + recHex + "    " + newCrc);
                    txtLogPage1.AppendText(Environment.NewLine);
                }));
            }
            //

            if (cbxComMode.Checked)
            {
                String[] arrs = recHex.Split('-');
                //01-04-00-00-00-20-F1-D2
                if (arrs.Length > 1)
                {
                    //读32位的数值
                    if (arrs[1] == "04" && arrs[2] == "00" && arrs[3] == "00" && arrs[4] == "00" && arrs[5] == "20")
                    {
                        byte[] datas = new byte[69];
                        datas[0] = (byte)0x01;
                        datas[1] = (byte)0x04;
                        datas[2] = (byte)0x40;
                        //
                        datas[3] = (byte)0x00;
                        datas[4] = (byte)0x01;

                        datas[5] = (byte)0x00;
                        datas[6] = (byte)0x01;

                        datas[7] = (byte)0x00;
                        datas[8] = (byte)0x01;

                        datas[9] = (byte)0x00;
                        datas[10] = (byte)0x01;

                        datas[11] = (byte)0x00;
                        datas[12] = (byte)0x01;

                        datas[13] = (byte)0x00;
                        datas[14] = (byte)0x01;

                        datas[15] = (byte)0x00;
                        datas[16] = (byte)0x01;

                        datas[17] = (byte)0x00;
                        datas[18] = (byte)0x01;

                        datas[19] = (byte)0x00;
                        datas[20] = (byte)0x01;

                        datas[21] = (byte)0x00;
                        datas[22] = (byte)0x01;
                        //
                        datas[23] = (byte)0x00;
                        datas[24] = (byte)0x01;

                        datas[25] = (byte)0x00;
                        datas[26] = (byte)0x01;

                        datas[27] = (byte)0x00;
                        datas[28] = (byte)0x01;

                        datas[29] = (byte)0x00;
                        datas[30] = (byte)0x01;

                        datas[31] = (byte)0x00;
                        datas[32] = (byte)0x01;

                        datas[33] = (byte)0x00;
                        datas[34] = (byte)0x01;

                        datas[35] = (byte)0x00;
                        datas[36] = (byte)0x01;

                        datas[37] = (byte)0x00;
                        datas[38] = (byte)0x01;

                        datas[39] = (byte)0x00;
                        datas[40] = (byte)0x01;

                        datas[41] = (byte)0x00;
                        datas[42] = (byte)0x01;
                        //
                        datas[43] = (byte)0x00;
                        datas[44] = (byte)0x01;

                        datas[45] = (byte)0x00;
                        datas[46] = (byte)0x01;

                        datas[47] = (byte)0x00;
                        datas[48] = (byte)0x01;

                        datas[49] = (byte)0x00;
                        datas[50] = (byte)0x01;

                        datas[51] = (byte)0x00;
                        datas[52] = (byte)0x01;

                        datas[53] = (byte)0x00;
                        datas[54] = (byte)0x01;

                        datas[55] = (byte)0x00;
                        datas[56] = (byte)0x01;

                        datas[57] = (byte)0x00;
                        datas[58] = (byte)0x01;

                        datas[59] = (byte)0x00;
                        datas[60] = (byte)0x01;

                        datas[61] = (byte)0x00;
                        datas[62] = (byte)0x01;
                        //
                        datas[63] = (byte)0x00;
                        datas[64] = (byte)0x01;

                        datas[65] = (byte)0x00;
                        datas[66] = (byte)0x01;
                        //
                        datas[67] = (byte)0x38;
                        datas[68] = (byte)0x33;

                        serialPort1.Write(datas, 0, datas.Length);
                    }
                }
            }
        }

        private void ToLights(Byte[] buffers)
        {
            if (buffers == null || buffers.Length < 32 + 2)
            {
                return;
            }
            byte address = buffers[0];
            byte command = buffers[1];
            byte startAddr = buffers[2];
            byte endAddr = buffers[3];
            byte[] datas = new byte[64];
            Array.Copy(buffers, 3, datas, 0, 32);
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            //byte[] bytes = getCommBytes();
            //serialPort1.Write(bytes, 0, bytes.Length);
            SendComm2SP();
        }

        private void SendComm2SP()
        {
            if (miSend == null)
            {
                miSend = new MethodInvoker(() =>
                {
                    byte[] bytes = getCommBytes();
                    serialPort1.Write(bytes, 0, bytes.Length);
                });
            }
            this.Invoke(miSend);
        }

        int Infinite = System.Threading.Timeout.Infinite;
        System.Threading.Timer CyclicTimer = null;
        MethodInvoker miSend = null;
        private void cbxSendCyclic_CheckedChanged(object sender, EventArgs e)
        {
            if (CyclicTimer == null)
            {
                CyclicTimer = new System.Threading.Timer(new TimerCallback((obj) =>
                {
                    SendComm2SP();
                }));
            }
            if (!cbxSendCyclic.Checked)
            {
                CyclicTimer.Change(Infinite, Infinite);
            }
            else
            {
                int dueTime = (int)nudCyclicValue.Value;
                CyclicTimer.Change(dueTime, dueTime);
            }
        }

        private void btnClearLogPage1_Click(object sender, EventArgs e)
        {
            txtLogPage1.Clear();
        }

        private Byte[] getCommBytes()
        {
            String xx = txtInputPage1.Text.Trim().Replace(" ", "").Replace("-", "").Replace(",", "");
            if (xx.Length % 2 != 0)
            {
                xx = xx + "0";
            }
            if (isAutoAddCRC.Checked)
            {
                xx += CRC.ToModbusCRC16(xx);
            }
            List<Byte> lists = new List<byte>();
            for (int x = 0; x < xx.Length; x = x + 2)
            {
                Byte b = Convert.ToByte(xx.Substring(x, 2), 16);
                lists.Add(b);
            }
            return lists.ToArray();
        }

        private void btnCompCRC_Click(object sender, EventArgs e)
        {
            Byte[] bytes = getCommBytes();
            txtLogPage1.AppendText(CRC.ToModbusCRC16(bytes));
            txtLogPage1.AppendText(Environment.NewLine);
        }

        private void btnAlarmClose_Click(object sender, EventArgs e)
        {
            byte[] comm = new byte[]{
                0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xCA
            };
            serialPort1.Write(comm, 0, comm.Length);
        }

        private void btnAlarmOpen_Click(object sender, EventArgs e)
        {
            byte[] comm = new byte[]{
                 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x8C, 0x3A
            };
            serialPort1.Write(comm, 0, comm.Length);
        }

        #endregion

        #region TagPage2

        private void BtnLoad2_Click(object sender, EventArgs e)
        {
            InitComports2();
        }

        private void InitCommands2()
        {
            List<KeyValuePair<String, String>> lists = new List<KeyValuePair<string, string>>();
            lists.Add(new KeyValuePair<string, string>("查询 GPRS 网络是否正常", "AT+CGREG?\r\n"));
            lists.Add(new KeyValuePair<string, string>("查询信号质量", "AT+CSQ\r\n"));
            lists.Add(new KeyValuePair<string, string>("选择第0个会话做为当前会话", "AT+QIFGCNT=0\r\n"));
            lists.Add(new KeyValuePair<string, string>("选择第1个会话做为当前会话", "AT+QIFGCNT=1\r\n"));
            lists.Add(new KeyValuePair<string, string>("设置 移动 VPN 接入点", "AT+QICSGP=1,\"CMWAP\"\r\n"));
            lists.Add(new KeyValuePair<string, string>("启动 TCPIP 服务", "AT+QIREGAPP\r\n"));
            lists.Add(new KeyValuePair<string, string>("激活 GPRS 无线链接", "AT+QIACT\r\n"));

            lists.Add(new KeyValuePair<string, string>("查询模块本地 IP 地址", "AT+QILOCIP\r\n"));
            lists.Add(new KeyValuePair<string, string>("关闭所有 PDP 上下文", "AT+QIDEACT\r\n"));

            lists.Add(new KeyValuePair<string, string>("关闭模块", "AT+QPOWD=1\r\n"));

            //
            lists.Add(new KeyValuePair<string, string>("查询彩信服务中心", "AT+QMMURL?\r\n"));
            lists.Add(new KeyValuePair<string, string>("配置彩信服务中心", "AT+QMMURL=\"http://mmsc.monternet.com\"\r\n"));
            lists.Add(new KeyValuePair<string, string>("查询彩信网关", "AT+QMMPROXY?\r\n"));
            lists.Add(new KeyValuePair<string, string>("配置彩信网关", "AT+QMMPROXY=1,\"10.0.0.172\",80\r\n"));
            lists.Add(new KeyValuePair<string, string>("获取彩信列表", "AT+QFLST\r\n"));
            lists.Add(new KeyValuePair<string, string>("设置内容为 UTF8 编码", "AT+QMMSW=\"utf8\",1\r\n"));
            lists.Add(new KeyValuePair<string, string>("清空彩信内容", "AT+QMMSW=0\r\n"));
            lists.Add(new KeyValuePair<string, string>("发送彩信", "AT+QMMSEND\r\n"));
            lists.Add(new KeyValuePair<string, string>("接收彩信通知", "AT+QMMSEND\r\n"));
            //

            //
            comboBox2.DataSource = lists;
            comboBox2.DisplayMember = "Key";
            comboBox2.ValueMember = "Value";
            //
            comboBox2.SelectedIndexChanged += comboBox2_SelectedIndexChanged;
            //
        }

        void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (sender is ComboBox)
            {
                ComboBox cb = sender as ComboBox;
                if (cb.SelectedIndex >= 0)
                {
                    txtInput2.Text = cb.SelectedValue.ToString();
                }
            }
        }

        private void InitComports2()
        {
            cmbxComports2.Items.Clear();
            cmbxComports2.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
            if (cmbxComports2.Items.Count > 0)
            {
                cmbxComports2.SelectedIndex = 0;
                btnOpen2.Enabled = true;
            }
            else
            {
                btnOpen2.Enabled = false;
            }
        }

        private void InitOthers()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("key");
            dt.Columns.Add("value");
            dt.Rows.Add("1", "彩信发送成功标识");
            dt.Rows.Add("2", "彩信下载成功标识");
            dt.Rows.Add("3", "收到新彩信标识");
            cmbxSmsTag.DataSource = dt;
            cmbxSmsTag.ValueMember = "key";
            cmbxSmsTag.DisplayMember = "value";
            cmbxSmsTag.DropDownStyle = ComboBoxStyle.DropDownList;
            //
            DataTable dt2 = new DataTable();
            dt2.Columns.Add("key");
            dt2.Columns.Add("value");
            dt2.Rows.Add("0", "未读短信");
            dt2.Rows.Add("1", "已读彩信");
            cmbSmsState.DataSource = dt2;
            cmbSmsState.ValueMember = "key";
            cmbSmsState.DisplayMember = "value";
            cmbSmsState.DropDownStyle = ComboBoxStyle.DropDownList;
            //
            var rr = Encoding.GetEncodings().Where(x => x.DisplayName.Contains("nicode")).ToList();
            cmbxCodePage.DataSource = rr;
            cmbxCodePage.ValueMember = "CodePage";
            cmbxCodePage.DisplayMember = "DisplayName";
        }

        private void BtnOpen2_Click(object sender, EventArgs e)
        {
            serialPort2.PortName = cmbxComports2.SelectedItem.ToString();
            serialPort2.BaudRate = 9600;
            serialPort2.DataBits = 8;
            serialPort2.StopBits = StopBits.One;
            serialPort2.Parity = Parity.None;
            serialPort2.Open();
            btnOpen2.Enabled = false;
            btnClose2.Enabled = true;
            cmbxComports2.Enabled = false;
        }

        private void BtnClose2_Click(object sender, EventArgs e)
        {
            serialPort2.Close();
            btnClose2.Enabled = false;
            btnOpen2.Enabled = true;
        }

        private void Button4_Click(object sender, EventArgs e)
        {
            if (!cbxAppend1A.Checked)
            {
                serialPort2.Write(txtInput2.Text);
            }
            else
            {
                serialPort2.Write(txtInput2.Text + (char)26);
            }
        }

        private void BtnSetSmsCenter_Click(object sender, EventArgs e)
        {
            txtInput2.Text = "AT+QMMURL=\"" + textBox4.Text.Trim() + "\"";
        }

        private void BtnQuerySmsCenter_Click(object sender, EventArgs e)
        {
            txtInput2.Text = "AT+QMMPROXY=1,\"" + textBox5.Text + "\",80";
        }

        private void BtnSetSmsPhone_Click(object sender, EventArgs e)
        {
            txtInput2.Text = "AT+QMMSW=1,1,\"" + textBox6.Text.Trim() + "\"";
        }

        private void BtnSendMsg_Click(object sender, EventArgs e)
        {
            serialPort2.WriteLine("AT+CMGF=1");
        }


        SmsMessage message = null;

        private void BtnSendMsgTxt_Click(object sender, EventArgs e)
        {
            message = new SmsMessage()
            {
                PhoneNumber = textBox6.Text.Trim(),
                UserData = textBox7.Text.Trim(),
            };

            serialPort2.WriteLine("AT+CMGF=0");
        }

        private void BtnString2Hex_Click(object sender, EventArgs e)
        {
            String str = textBox7.Text.Trim();
            //EncodingInfo[] infos = Encoding.GetEncodings();
            //EncodingInfo info = infos.Where(x => x.DisplayName.Contains("GB") && x.DisplayName.Contains("2312")).FirstOrDefault();            //EncodingInfo[] infos = Encoding.GetEncodings();
            Encoding gb2312 = Encoding.GetEncoding(936);
            byte[] bytes = gb2312.GetBytes(str);
            textBox8.Text = BitConverter.ToString(bytes, 0, bytes.Length).Replace("-", "");
        }

        private void BtnHex2String_Click(object sender, EventArgs e)
        {
            String code = textBox8.Text.Trim().Replace("-", "").Replace(" ", "");
            Encoding gb2312 = Encoding.GetEncoding(936);
            if (code.Length % 2 != 0)
            {
                MessageBox.Show("长度不是偶数，不能转化");
                return;
            }
            try
            {
                byte[] bytes = new byte[code.Length / 2];
                for (int i = 0; i < code.Length; i = i + 2)
                {
                    String t = code.Substring(i, 2);
                    bytes[i / 2] = Convert.ToByte(t, 16);
                }
                textBox7.Text = gb2312.GetString(bytes);
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }

        private void BtnUCS2HEX_Click(object sender, EventArgs e)
        {
            String str = textBox7.Text.Trim();
            int codePage = (int)cmbxCodePage.SelectedValue;
            Encoding info = Encoding.GetEncoding(codePage);
            byte[] bytes = info.GetBytes(str);
            textBox8.Text = BitConverter.ToString(bytes, 0, bytes.Length).Replace("-", "");
        }

        private void BtnSmsCenter_Click(object sender, EventArgs e)
        {
            serialPort2.WriteLine("AT+CSCA?");
        }

        #endregion

        #region tabPage3

        private void BtnLoadComs3_Click(object sender, EventArgs e)
        {
            initPage3();
        }

        private void initPage3()
        {
            cmbxComPage3.Items.Clear();
            cmbxComPage3.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
            if (cmbxComPage3.Items.Count > 0)
            {
                cmbxComPage3.SelectedIndex = 0;
                btnOpenCom3.Enabled = true;
                btnCloseCom3.Enabled = true;
            }
            else
            {
                btnOpenCom3.Enabled = false;
                btnCloseCom3.Enabled = false;
            }
        }

        private void BtnOpenCom3_Click(object sender, EventArgs e)
        {
            if (cmbxComPage3.Items.Count == 0)
            {
                return;
            }

            serialPort4.Close();
            serialPort4.BaudRate = 9600;
            serialPort4.StopBits = StopBits.One;
            serialPort4.DataBits = 8;
            serialPort4.Parity = Parity.None;
            serialPort4.ReceivedBytesThreshold = 21;
            serialPort4.PortName = cmbxComPage3.SelectedItem.ToString();
            //
            try
            {
                serialPort4.Open();
            }
            catch (Exception exc)
            {
                AppendLineComTxt(exc.Message);
            }
        }

        private void BtnCloseCom3_Click(object sender, EventArgs e)
        {
            serialPort4.Close();
        }

        System.Threading.Timer timerPage3 = null;
        String excepAddr = String.Empty;

        private void BtnAutoSend3_Click(object sender, EventArgs e)
        {
            int v = Convert.ToInt32(nudInterval3.Value);

            if (timerPage3 != null)
            {
                timerPage3.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
            }

            timerPage3 = new System.Threading.Timer(new TimerCallback((obj) =>
            {
                if (serialPort4.IsOpen)
                {
                    int addr = (int)nudDevAddr.Value;
                    string comm = string.Concat(addr.ToString("X2"), " 04 00 40 00 08 ");
                    string commfull = string.Concat(comm, CRC.ToModbusCRC16(comm));
                    byte[] data = CRC.StringToHexByte(commfull);
                    serialPort4.Write(data, 0, data.Length);
                }
            }), null, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);

            excepAddr = GetExceptAddr();
            timerPage3.Change(0, v);
        }

        private void BtnStopAuto3_Click(object sender, EventArgs e)
        {
            if (timerPage3 != null)
            {
                timerPage3.Change(Timeout.Infinite, Timeout.Infinite);
            }
        }

        private void AppendLineComTxt(string txt)
        {
            txtCOMOutput.Invoke(new MethodInvoker(() =>
            {
                txtCOMOutput.AppendText(txt + Environment.NewLine);
            }));
        }

        private void AppendLineReaderNums(int[] txt)
        {
            object[] yy = new object[8];
            for (int x = 0; x < txt.Length; x++)
            {
                if (x < 8)
                    yy[x] = txt[x];
            }

            dataGridView1.BeginInvoke(new MethodInvoker(() =>
            {
                if (dataGridView1.Columns.Count == 0)
                {
                    dataGridView1.Columns.Add("addr", "addr");
                    dataGridView1.Columns.Add("ain0", "ain0");
                    dataGridView1.Columns.Add("ain1", "ain1");
                    dataGridView1.Columns.Add("ain2", "ain2");
                    dataGridView1.Columns.Add("ain3", "ain3");
                    dataGridView1.Columns.Add("ain4", "ain4");
                    dataGridView1.Columns.Add("ain5", "ain5");
                    dataGridView1.Columns.Add("ain6", "ain6");
                    dataGridView1.Columns.Add("ain7", "ain7");

                    dataGridView1.RowPostPaint += UtilityHelper.DataGridViewRowPostPaint;
                }
                dataGridView1.Rows.Add(yy);
            }));
        }

        private void SerialPort4_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //Thread.Sleep(300);
            SerialPort serialPort = sender as SerialPort;
            if (!serialPort.IsOpen)
                return;
            byte[] temp = new byte[1024];
            int size = serialPort.Read(temp, 0, temp.Length);
            int addr485 = temp[0];
            byte[] data = temp.Take(size).ToArray();
            //
            if (timerPage3 != null)
            {
                timerPage3.Change(0, System.Threading.Timeout.Infinite);
            }
            //
            if (data.Length <= 3)
            {
                return;
            }
            if (temp[0] != 6)
            {
                return;
            }
            AppendLineComTxt(BitConverter.ToString(data));
            //
            byte[] crcbyte = data.Skip(data.Length - 2).Take(2).ToArray();
            byte[] databyte = data.Take(data.Length - 2).ToArray();
            string qq1 = CRC.ToModbusCRC16(databyte);
            string qq2 = CRC.ByteToString(crcbyte, false);
            if (qq1 != qq2)
            {
                return;
            }

            byte b = data[2];
            byte[] txp = data.Skip(3).Take(b).ToArray();
            byte[] motordata = null;
            if (txp.Length % 2 != 0)
            {
                motordata = new byte[txp.Length + 1];
                Array.Copy(txp, 0, motordata, 0, txp.Length);
            }
            else
            {
                motordata = txp;
            }
            int[] datas = new int[1 + b / 2];
            datas[0] = addr485;
            for (int i = 0; i < motordata.Length / 2; i++)
            {
                byte[] xx = motordata.Skip(i * 2).Take(2).ToArray();
                int x1 = System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt16(xx, 0));
                datas[i + 1] = x1;
            }
            //
            AppendLineReaderNums(datas);

            int v = Convert.ToInt32(nudInterval3.Value);
            timerPage3.Change(0, v);
        }

        private delegate string StringValueHandler();
        StringValueHandler stringValueHandler;

        private string GetExceptAddr()
        {
            if (stringValueHandler == null)
            {
                stringValueHandler = new StringValueHandler(() =>
                {
                    int addri = (int)nudExceptAddr.Value;
                    return addri.ToString("X2");
                });
            }
            string addr = stringValueHandler.Invoke();
            return addr;
        }

        #endregion

        private void btnBeep_Click(object sender, EventArgs e)
        {
            var uh = new UtilityHelper();
            //UtilityHelper.Beep(500, 700);
            UtilityHelper.Beep();

            uh.SleepMilliseconds(2000);

            System.Console.Beep();

            uh.SleepMilliseconds(2000);

            System.Media.SystemSounds.Beep.Play();

            uh.SleepMilliseconds(2000);

            //System.Media.SystemSounds.Question.Play();

            //uh.SleepMilliseconds(2000);

        }
    }
}